/*  
  -- The Lime II Project -- 

  A tuplespaces-based middleware for coordinating agents and mobile hosts.
  Copyright (C) 2005.
  Gian Pietro Picco, Amy L. Murphy, Lorenzo Bellini.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  Lesser General Public License for more details.

  You should have received this copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 */

package lime2;

/**
 * Defines various (static) constants. Please note that static initialization
 * occurs only if it is necessary: these values are initialized as soon as they
 * are required.
 * 
 * @author Gian Pietro Picco
 * @author Amy Murphy
 * @author Lorenzo Bellini
 */

public interface LimeConstants {
	// the following constants describe the fragmentation options (please note
	// that support for fragmentation can be independently enabled/disabled wrt
	// sending/receiving)

	/**
	 * If it is true, then outgoing remote ops whose size is greater than
	 * SIZE_LIMIT are fragmented into several FragmentOps with size <=
	 * SIZE_LIMIT.
	 */
	final static boolean FRAGMENT_OUTGOING_ENABLED = LimeServer
			.booleanProperty(PropertyKeys.FRAGM_OUT_KEY);

	/**
	 * If it is true, then incoming fragments will be re-assembled; otherwise
	 * they are just ignored.
	 */
	final static boolean DEFRAGMENT_INCOMING_ENABLED = LimeServer
			.booleanProperty(PropertyKeys.DEFRAG_IN_KEY);

	/**
	 * The maximum size (in bytes) of an outgoing remote op, if outgoing
	 * fragmentation is turned on. This value must be greater than the size of a
	 * header-only remote op (which is less than 500 bytes).
	 */
	final static int SIZE_LIMIT = LimeServer
			.intProperty(PropertyKeys.FRAGS_SIZ_KEY);

	/**
	 * The maximum amount of time (in milliseconds) that can elapse between the
	 * arrivals of two fragments; if this timeout is not respected, the
	 * re-assembly process is aborted. This value must be less than (standard)
	 * TIMEOUT.
	 */
	final static long REASSEMBLY_TIMEOUT = LimeServer
			.longProperty(PropertyKeys.FRAGS_RTM_KEY);

	/**
	 * The number of defrag attempts that are scheduled during a reassembly
	 * timeout.
	 */
	final static long DEFRAG_SCHEDULED = LimeServer
			.longProperty(PropertyKeys.FRAGS_DFS_KEY);

	/**
	 * The estimated amount of time (in milliseconds) for defragmenting a single
	 * fragment. This value is used for extending the timeout of the thread
	 * sending the fragments.
	 */
	final static long DEFRAG_OVERHEAD = LimeServer
			.longProperty(PropertyKeys.FRAGS_OVR_KEY);

	// the following constant describes the size of the thread pool within the
	// CommunicationMgr

	/**
	 * The number of threads mantained by the thread pool of the
	 * CommunicationMgr.
	 */
	final static int POOLED_THREADS = LimeServer
			.intProperty(PropertyKeys.THREADSPL_KEY);

	// the following constants enable caching of remote ops to protect against
	// duplicated messages (duplication is critical in the case of PASSIVE_OPEN
	// requests: multiple protocols are started)

	/**
	 * If it is true, the CommunicationMgr caches incoming remote ops in order
	 * to protect against duplicated messages.
	 */
	final static boolean CACHE_DUPS_ENABLED = LimeServer
			.booleanProperty(PropertyKeys.CACHE_DUP_KEY);

	/** Size of the duplication cache. */
	final static int CACHE_DUPS_SIZE = LimeServer
			.intProperty(PropertyKeys.CACHE_SIZ_KEY);

	// the following constant describes the number of retries when partial
	// communication failure occurs

	/** Number of retries allowed in case of partial communication failures. */
	final static int RETRIES = LimeServer
			.intProperty(PropertyKeys.CA_RETRYF_KEY);;

	// the following constants describe parameters for dis/engagement

	/**
	 * The time (in milliseconds) that has to elapse between two advertising
	 * messages.
	 */
	final static long DETECT_PHASE = LimeServer
			.longProperty(PropertyKeys.DETECT_PH_KEY);

	/**
	 * The time (in milliseconds) that has to elapse between two mesh
	 * information broadcast
	 */
	final static long MESH_BROADCAST_PHASE = LimeServer
			.longProperty(PropertyKeys.MESH_BROADCAST_PH_KEY);

	/**
	 * The timeout (in milliseconds) after which a silent host is declared dead.
	 */
	final static long DEAD_HOST_TIMEOUT = LimeServer
			.longProperty(PropertyKeys.DELETE_TM_KEY);

	/**
	 * Forces the LimeSystemTupleSpace to be refreshed immediately when the Lime
	 * group changes: maximum consistency, but maximum overhead.
	 */
	final static boolean FORCE_MAX_REFRESH = LimeServer
			.booleanProperty(PropertyKeys.RFRSH_MAX_KEY);

	/**
	 * If FORCE_MAX_REFRESH is turned off then the LimeSystemTupleSpace is
	 * refreshed periodically, every PHASE_N advertising messages. This value
	 * must be greater than zero.
	 */
	final static int PHASES_N = LimeServer
			.intProperty(PropertyKeys.ADV_PHASE_KEY);

	// the following constants define parameters for enabling "non lazy"
	// reconciliation

	/**
	 * If two hosts stay connected for an amount of time greater than this value
	 * (in milliseconds) and they are not reconciled, we run reconciliation.
	 */
	final static long NO_LAZY_TIME = LimeServer
			.longProperty(PropertyKeys.NOL_TIMER_KEY);

	/**
	 * The sleep time (in milliseconds) of the thread that enables "non lazy"
	 * reconciliation.
	 */
	final static long NO_LAZY_SLEEP_TIME = LimeServer
			.longProperty(PropertyKeys.NOL_SLEEP_KEY);

	// the following constant describes the size of the receiving buffer for
	// datagrams (regards all UDP communication)

	/**
	 * Size (in bytes) of the receiving buffer for datagrams (.. multicast). It
	 * must be big enough to store a message "fully".
	 */
	final static int UDP_BUFFER_SIZE = LimeServer
			.intProperty(PropertyKeys.UDP_BUFFR_KEY);

	// the following constants define standard timeouts for remote protocols

	/** The standard timeout (in milliseconds) for waiting a remote reply. */
	final static long TIMEOUT = LimeServer
			.longProperty(PropertyKeys.STD_TIMER_KEY);

	/** The multiplying factor for the Rem-Inp-Multi PassiveOpen protocol. */
	final static int FACTOR_INGG = LimeServer
			.intProperty(PropertyKeys.FACT_INGG_KEY);

	// the following constant describes the maximum number of
	// tuples/reactions/reaction ids a single remote message can carry

	/**
	 * The maximum number of tuples/reactions/etc.. a single remote message can
	 * carry.
	 */
	final static int PACK_SIZE = LimeServer
			.intProperty(PropertyKeys.PACKED_SZ_KEY);

	// the following constants enable/disable features of the PlainCA

	/**
	 * If it is true, then PlainCA re-uses TCP connections; otherwise a new
	 * connection is established for every message.
	 */
	final static boolean CACHE_TCP_CONNECTIONS = LimeServer
			.booleanProperty(PropertyKeys.CACHE_TCP_KEY);

	/** If it is true, then PlainCA forces keep-alive on TCP sockets. */
	final static boolean KEEP_ALIVE = LimeServer
			.booleanProperty(PropertyKeys.KEEPA_TCP_KEY);

	// the following constant enables/disables the MsgTestCA

	/**
	 * If it is true, then the concrete communication adapter is decorated with
	 * the printing of messages.
	 */
	final static boolean SHOW_MSG = LimeServer
			.booleanProperty(PropertyKeys.DO_SEEMSG_KEY);

	// the following constants set tuplespace-related properties

	/**
	 * Maximum length allowed for a tuplespace name; since tuplespace names are
	 * carried by remote ops, too long ones would result into overhead of
	 * communication.
	 */
	final static int NAME_LENGTH_LIMIT = LimeServer
			.intProperty(PropertyKeys.NAME_LMAX_KEY);

	/**
	 * If the number of tuples to out exceeds this limit, then Reactor switches
	 * from many "out" operations to a single "outg" operation; this can be
	 * useful to calibrate write overhead of the underlying tuplespace engine.
	 */
	final static int FORCE_GROUP_OPERATION = LimeServer
			.intProperty(PropertyKeys.FORCE_GWR_KEY);

	// the following constants describe parameters for the LimeSystemTupleSpace

	/** The reserved name for the system tuplespace. */
	final static String SYSTEM_NAME = LimeServer
			.stringProperty(PropertyKeys.LSYS_NAME_KEY);

	/** The policy for the system tuplespace. */
	final static byte SYSTEM_POLICY = LimeServer
			.byteProperty(PropertyKeys.LSYS_POLC_KEY);

	/** The policy for the multicast policy */
	final static boolean TREE_MULTICAST = LimeServer
			.booleanProperty(PropertyKeys.TREE_MULTICAST_KEY);

	// the following constants describe the position of the "system information"
	// fields within a limified tuple

	/** Position of the ID within a "limified" ITuple. */
	final static int ID_TAG = 0;

	/** Position of the current Location within a "limified" ITuple. */
	final static int CUR_TAG = 1;

	/** Position of the destination Location within a "limified" ITuple. */
	final static int DEST_TAG = 2;

	/** Number of "system tags" in a "limified" ITuple. */
	final static int TAGS_NUMBER = 3;

	// the following constants describe the legal codes for Op.type

	// legal codes for LocalOp.type

	// legal codes for TupleOp.type

	/** Rd. */
	final static byte RD = 1;

	/** Rdg. */
	final static byte RDG = 2;

	/** Rdp. */
	final static byte RDP = 3;

	/** In. */
	final static byte IN = 4;

	/** Ing. */
	final static byte ING = 5;

	/** Inp. */
	final static byte INP = 6;

	/** Update */
	final static byte UPDATE = 7;

	/** Update Replica */
	final static byte UPDATE_REPLICA = 8;

	/** Out. */
	final static byte OUT = 9;

	/** Outg. */
	final static byte OUTG = 10;

	/* Out to multi */
	final static byte OUTM = 11;

	// end of codes for TupleOp.type

	// legal codes for ReactionOp.type

	/** Install strong reactions. */
	final static byte INSTALL_STRONG = 15;

	/** Remove strong reactions. */
	final static byte REMOVE_STRONG = 16;

	/** Install weak reactions. */
	final static byte INSTALL_WEAK = 17;

	/** Remove weak reactions. */
	final static byte REMOVE_WEAK = 18;

	// end of codes for ReactionOp.type

	// legal codes for WeakOp.type

	/** Weak reaction triggered. */
	final static byte EVENTW = 20;

	// end of codes for WeakOp.type

	// end of codes for LocalOp.type

	// legal codes for RemoteOp.type

	// legal codes for RemTupleOp.type

	/** Remote rdg. */
	final static byte REM_RDG_UNI = 25;
	final static byte REM_RDG_MULTI = 26;

	/** Remote rdp. */
	final static byte REM_RDP_UNI = 27;
	final static byte REM_RDP_MULTI = 28;

	/** Remote ing. */
	final static byte REM_ING_UNI = 29;
	final static byte REM_ING_MULTI = 30;

	/** Remote inp. */
	final static byte REM_INP_UNI = 31;
	final static byte REM_INP_MULTI = 32;

	/** Remote out. */
	final static byte REM_OUT = 33;

	/** Remote outg. */
	final static byte REM_OUTG = 34;

	final static byte REM_UPDATE_UNI = 35;

	/* Remote out by multicast */
	final static byte REM_OUT_MULTI = 36;

	// end of codes for RemTupleOp.type

	// legal codes for RemReactionOp.type

	/** Install remote weak reactions. */
	final static byte REM_INSTALL_UNI = 40;
	final static byte REM_INSTALL_MULTI = 41;

	/** Remove remote weak reactions. */
	final static byte REM_REMOVE_UNI = 42;
	final static byte REM_REMOVE_MULTI = 43;

	// end of codes for RemReactionOp.type

	// legal codes for RemWeakOp.type

	/** Remote weak reaction triggered. */
	final static byte REM_EVENTW = 44;

	/** Remote read triggered. */
	final static byte REM_RDW = 45;

	/** Remote in triggered. */
	final static byte REM_INW = 46;

	// end of codes for RemWeakOp.type

	// legal codes for FragmentOp.type

	/** Fragment. */
	final static byte FRAGMENT = 47;

	// end of codes for FragmentOp.type

	// legal codes for RemReconcileOp.type //

	/** Reconcile. */
	final static byte RECONCILE = 50;

	/** Reconcile No Lazy. */
	final static byte RECONCILE_NO_LAZY = 55;

	/**
	 * All external operation types should use this constant as their base value
	 */
	final static byte EXT_OP_TYPE_BASE = 60;

	/**
	 * custom operation for tuple type information's exchange, which is used by
	 * decision maker.
	 */
	final static byte TUPLE_TYPE_INFO_EXCHANGE = EXT_OP_TYPE_BASE + 1;

	// end of codes for RemReconcileOp.type //

	// end of codes for RemoteOp.type

	// end of codes for Op.type

	// the following constants describe the legal codes for (header) subtype in
	// RemoteOp

	/** Open. */
	final static byte OPEN = 1;

	/** Passive open. */
	final static byte PASSIVE_OPEN = 2;

	/** Reply. */
	final static byte REPLY = 3;

	/** Rejected. */
	final static byte REJECT = 4;

	/** Ack. */
	final static byte ACK = 5;

	/** Fin. */
	final static byte FIN = 6;

	// end of codes for (header) subtype in RemoteOp

	// the following constants describe the legal codes for type in EngMsg

	/** Hello. */
	final static byte HELLO = 0;

	/** Bye. */
	final static byte BYE = 111;

	/** HELLO_REPLY. */
	final static byte HELLO_REPLY = 8;

	/** Mesh Info Exchange */
	final static byte MESH_INFO = 9;
	// end of codes for type in EngMsg

}
